  * Fix job control bug in non-interactive scripts (closes: #296446)
    Many thanks to Paul Stroud <pstroud@gmail.com> for the patch.
  * lex.c: Don't expand aliases if there's an opening bracket just after
    the token. Fixes unreported problem with pdksh reporting syntax error
    on the init scripts that define function named `stop' (clashing
    with an built-in alias.)
Index: pdksh-5.2.14/jobs.c
===================================================================
--- pdksh-5.2.14.orig/jobs.c	2009-07-18 15:20:19.000000000 +0200
+++ pdksh-5.2.14/jobs.c	2009-07-18 15:20:27.000000000 +0200
@@ -340,12 +340,17 @@
 	int i;
 
 	if (Flag(FMONITOR)) {
-		/* Don't call get_tty() 'til we own the tty process group */
-		tty_init(FALSE);
+		int use_tty;
+		if (Flag(FTALKING)) {
+			/* Don't call get_tty() 'til we own the tty process group */
+			use_tty = 1;
+			tty_init(FALSE);
+		} else
+			use_tty = 0;
 
 # ifdef TTY_PGRP
 		/* no controlling tty, no SIGT* */
-		ttypgrp_ok = tty_fd >= 0 && tty_devtty;
+               ttypgrp_ok = use_tty && tty_fd >= 0 && tty_devtty;
 
 		if (ttypgrp_ok && (our_pgrp = getpgID()) < 0) {
 			warningf(FALSE, "j_init: getpgrp() failed: %s",
@@ -401,8 +406,10 @@
 					strerror(errno));
 		}
 #  endif /* NTTYDISC && TIOCSETD */
-		if (!ttypgrp_ok)
-			warningf(FALSE, "warning: won't have full job control");
+		if (Flag(FTALKING)) {
+			if (!ttypgrp_ok)
+				warningf(FALSE, "warning: won't have full job control");
+		}
 # endif /* TTY_PGRP */
 		if (tty_fd >= 0)
 			get_tty(tty_fd, &tty_state);
Index: pdksh-5.2.14/lex.c
===================================================================
--- pdksh-5.2.14.orig/lex.c	2009-07-18 15:20:19.000000000 +0200
+++ pdksh-5.2.14/lex.c	2009-07-18 15:20:27.000000000 +0200
@@ -723,7 +723,15 @@
 #endif /* KSH */
 		)	/* ONEWORD? */
 		return LWORD;
-	ungetsc(c);		/* unget terminator */
+
+	/* unget terminator */
+	ungetsc(c);
+
+	/*
+	 * note: the alias-vs-function code below depends on several
+	 * interna: starting from here, source->str is not modified;
+	 * the way getsc() and ungetsc() operate; etc.
+	 */
 
 	/* copy word to unprefixed string ident */
 	for (sp = yylval.cp, dp = ident; dp < ident+IDENT && (c = *sp++) == CHAR; )
@@ -747,6 +755,33 @@
 		if ((cf & ALIAS) && (p = tsearch(&aliases, ident, h))
 		    && (p->flag & ISSET))
 		{
+			/*
+			 * this still points to the same character as the
+			 * ungetsc'd terminator from above
+			 */
+			const char *cp = source->str;
+
+			/* prefer POSIX but not Korn functions over aliases */
+			while (*cp == ' ' || *cp == '\t')
+				/*
+				 * this is like getsc() without skipping
+				 * over Source boundaries (including not
+				 * parsing ungetsc'd characters that got
+				 * pushed into an SREREAD) which is what
+				 * we want here anyway: find out whether
+				 * the alias name is followed by a POSIX
+				 * function definition (only the opening
+				 * parenthesis is checked though)
+				 */
+				++cp;
+			/* prefer functions over aliases */
+			if (*cp == '(' /*)*/) {
+				/*
+				 * delete alias upon encountering function
+				 * definition
+				 */
+			tdelete(p);
+		    } else {
 			register Source *s;
 
 			for (s = source; s->type == SALIAS; s = s->next)
@@ -760,6 +795,7 @@
 			source = s;
 			afree(yylval.cp, ATEMP);
 			goto Again;
+                    }
 		}
 	}
 
Index: pdksh-5.2.14/ksh.Man
===================================================================
--- pdksh-5.2.14.orig/ksh.Man	2009-07-18 15:20:07.000000000 +0200
+++ pdksh-5.2.14/ksh.Man	2009-07-18 15:21:11.000000000 +0200
@@ -390,6 +390,7 @@
 .IP "\fIname\fP \fB()\fP \fIcommand\fP"
 Mostly the same as \fBfunction\fP.
 See Functions below.
+Whitespace (space or tab) after \fIname\fP will be ignored most of the time.
 .\"}}}
 .\"{{{  time [-p] [ pipeline ]
 .IP "\fBtime\fP [ \fB-p\fP ] [ \fIpipeline\fP ]"
@@ -1457,6 +1458,10 @@
 so \fBgetopts\fP can be used properly both inside and outside the function
 (Bourne-style functions leave \fBOPTIND\fP untouched, so using \fBgetopts\fP
 inside a function interferes with using \fBgetopts\fP outside the function).
+.br
+Bourne-style function definitions take precedence over alias dereferences
+and remove alias definitions upon encounter, while aliases take precedence
+over Korn-style functions.
 .nr PD \n(P2
 In the future, the following differences will also be added:
 .nr P2 \n(PD
